const util = require('util')
const dayjs = require('dayjs')
const ms = require('ms')
const jwt = require('jsonwebtoken')
const verify = util.promisify(jwt.verify)
const { Controller } = require('egg')

class WechatController extends Controller {
  // 微信用户信息
  async userInfo() {
    const { ctx } = this
    const { wechat } = ctx.session

    ctx.body = {
      code: 0,
      msg: 'success',
      data: wechat,
    }
  }

  // 微信H5授权
  async auth() {
    const { ctx } = this
    const { query } = ctx

    const wechat = ctx.session.wechat
    let url = decodeURIComponent(query.callbackUrl || '/')
    if (url.indexOf('?') == -1) {
      url += `?openId=${wechat.openId}`
    } else {
      url += `&openId=${wechat.openId}`
    }

    ctx.redirect(url)
  }

  // 授权登录
  async login() {
    const { ctx } = this

    const url = await this.service.userAccount.wechatMpLogin(
      ctx.session.wechat,
      ctx.query.url ? decodeURIComponent(ctx.query.url) : null
    )

    ctx.redirect(url)
  }

  // 微信公众号JS-SDK
  async jsSdk() {
    const { ctx } = this
    const { wechatApi } = this.app
    const { query } = ctx
    const url = decodeURIComponent(query.url)

    const jsSdkConfig = await wechatApi.mp.getJsSdkConfig(url, {
      // accessToken: await this.service.config.getAccessToken(),
      jsapiTicket: await this.service.config.getJsapiTicket(),
    })

    ctx.body = {
      code: 0,
      msg: 'success',
      data: jsSdkConfig,
    }
  }

  // 微信授权回调
  async oauth2Callback() {
    const { ctx, config } = this
    const { wechatApi } = this.app
    const { query } = ctx
    const authConfig = config.wechat.auth
    const { expireIn } = authConfig

    // ?url=%2Ftest%2Fwechat-auth&code=091LGqll21EhJ74Q9sll2onNDH1LGqlc&state=STATE

    if (!query.code) throw '授权失败'

    // {
    //     access_token: '36_CYNf2-x9CYcYYScaXGmGuzePXYeerwExOrZgXz84Q976m5doX-u6CEgdscSZN011lZWVSlZx3U4wD_tkIh0MyA',
    //     expires_in: 7200,
    //     refresh_token: '36_ceiDBb17XTJZI6VZvnsJFKRVcM3QGfthptISiWqyt6E2X65lYAH5PQfewxZCZTapYzYb65APU-_B7j2mDvsD1w',
    //     openid: 'obcwfwX4FQ7au74hX4iInsVaIySU',
    //     scope: 'snsapi_userinfo',
    //     unionid: 'ovVYzwui96At96qxmpeBoBVWPOSI'
    // }
    const tokenInfo = await wechatApi.mp.getAuthAccessToken({
      code: query.code,
    })

    // 授权用户信息
    let authUserInfo

    // 基础信息
    if (tokenInfo.scope == 'snsapi_base') {
      authUserInfo = {
        openid: tokenInfo.openid,
        unionid: tokenInfo.unionid,
      }
    }
    // 完整信息
    else if (tokenInfo.scope == 'snsapi_userinfo') {
      authUserInfo = await wechatApi.mp.getAuthUserInfo({
        access_token: tokenInfo.access_token,
        openid: tokenInfo.openid,
        lang: 'zh_CN ',
      })
    }

    if (!authUserInfo) throw '用户信息获取失败'

    // {
    //     openid: 'obcwfwX4FQ7au74hX4iInsVaIySU',
    //     nickname: '路途',
    //     sex: 1,
    //     language: 'zh_CN',
    //     city: 'Chengdu',
    //     province: 'Sichuan',
    //     country: 'China',
    //     headimgurl: 'http://thirdwx.qlogo.cn/mmopen/vi_32/Qps8eiaZjuicH8iahpVmqeLpZRGuV8tTvamCrqXVfk0JQud1JqlRibu9iaJrfN1CnxuRKMzwU1jGp3yRQa6q5DLbr1Q/132',
    //     privilege: [],
    //     unionid: 'ovVYzwui96At96qxmpeBoBVWPOSI'
    // }

    const newWechatUser = {
      openId: authUserInfo.openid,
      avatar: authUserInfo.headimgurl,
      nickname: authUserInfo.nickname,
      unionId: authUserInfo.unionid,
      gender: authUserInfo.gender,
      country: authUserInfo.country,
      province: authUserInfo.province,
      city: authUserInfo.city,
    }

    const expire = dayjs().add(ms(expireIn), 'ms')
    ctx.session.wechat = {
      ...newWechatUser,
      _expire: expire.unix(),
      _expireFormat: expire.format('YYYY-MM-DD HH:mm:ss'),
    }

    const wechatUser = await ctx.model.WechatUser.findOne({
      openId: newWechatUser.openId,
    })

    if (wechatUser) {
      await ctx.model.WechatUser.updateOne({ _id: wechatUser._id }, newWechatUser)
    } else {
      await ctx.model.WechatUser.create(newWechatUser)
    }

    ctx.redirect(decodeURIComponent(query.url))
  }

  /**
     * @api {get} /wechat/access-token [微信小程序] 获取Access token
     * @apiGroup 账号
     * @apiVersion 0.0.0
     * 
     * @apiSuccess {Int} code 状态码 <br /> 0、成功 <br /> 1、失败
     * @apiSuccess {String} msg  success
     * @apiSuccess {Object} data
     * 
     * @apiSuccessExample {json} Success-Response:
    {
        "code": 0,
        "msg": "success"
    }
     */
  async getAccessToken() {
    const { ctx } = this
    const accessAoken = await this.service.config.getAccessToken()

    ctx.body = {
      code: 0,
      msg: 'success',
      data: { accessAoken },
    }
  }

  /**
     * @api {get} /wechat/jsapi-ticket [微信小程序] 获取jsapi-tick
     * @apiGroup 账号
     * @apiVersion 0.0.0
     * 
     * @apiSuccess {Int} code 状态码 <br /> 0、成功 <br /> 1、失败
     * @apiSuccess {String} msg  success
     * @apiSuccess {Object} data
     * 
     * @apiSuccessExample {json} Success-Response:
    {
        "code": 0,
        "msg": "success"
    }
     */
  async getJsapiTicket() {
    const { ctx } = this
    const jsapiTicket = await this.service.config.getJsapiTicket()

    ctx.body = {
      code: 0,
      msg: 'success',
      data: { jsapiTicket },
    }
  }
}

module.exports = WechatController
